package apobates.gui.formatter.component.progress.ball;

import apobates.gui.formatter.util.Core;
import javafx.scene.control.Label;
import javafx.scene.control.SkinBase;
import javafx.scene.effect.Blend;
import javafx.scene.effect.BlendMode;
import javafx.scene.effect.Shadow;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Path;
import javafx.scene.shape.Rectangle;
import javafx.scene.shape.Shape;

/**
 * 进度球皮肤
 * @author xiaofanku
 * @since 20230410
 */
public class BallProgressIndicatorSkin extends SkinBase<BallProgressIndicator> {
    private final BallProgressIndicator indicator;
    private StackPane container = new StackPane();
    // 进度圆
    private Circle progessCir=new Circle();
    // 揭盖层
    private Rectangle coverRec=new Rectangle();
    // 整体轮廓
    private Circle outlineCir = new Circle();
    // 进度值
    private final Label percentLabel = new Label();
    // 进度着色(圆的一部分)
    private Path paintPath = new Path();
    /**
     * Constructor for all SkinBase instances.
     *
     * @param control The control for which this Skin should attach to.
     */
    public BallProgressIndicatorSkin(BallProgressIndicator control) {
        super(control);
        this.indicator = control;
        initContainer(indicator);
        initStyles();
        getChildren().add(this.container);
        // 更新进度
        this.indicator.progressProperty().addListener((o, oldVal, newVal) -> {
            // System.out.println("[BPS]new value:"+newVal.intValue()+", old value:"+oldVal.intValue());
            /* 更新进度值(0-100) */
            setProgressLabel(newVal.intValue());
            // 更新着色区域
            double v = this.container.getHeight() * ((100 - newVal.intValue()) / 100d);
            this.updateWaterline(v);
        });
    }
    // 初始化组件
    private void initContainer(BallProgressIndicator control){
        double widthPrefSize = control.getPrefWidth();
        double heightPrefSize = control.getPrefHeight();
        // 圆
        progessCir.setCenterX(widthPrefSize/2);
        progessCir.setCenterY(heightPrefSize/2);
        progessCir.setRadius(widthPrefSize/2);
        // 缺少这个将是致命的
        progessCir.setStroke(Color.TRANSPARENT);
        // 矩形
        coverRec.setWidth(widthPrefSize);
        coverRec.setHeight(heightPrefSize);
        coverRec.setX(0.0f);
        coverRec.setY(0.0f);
        // coverRec.setFill(Color.BLUE);
        // 裁剪出进度图形
        // intersect: 无所为
        // subtract: 哪个在前少的哪部分在前
        this.paintPath = (Path) Shape.subtract(this.progessCir, this.coverRec);
        // CSS样式: ballindicator-filler-circle
        // paintPath.setFill(Color.BLUE);  //?填充色
        // paintPath.setStroke(Color.BLUE); //?填充色
        // 整体轮廓
        this.outlineCir.setCenterX(widthPrefSize/2);
        this.outlineCir.setCenterY(heightPrefSize/2);
        this.outlineCir.setRadius(widthPrefSize/2);
        // ------------------------------------------------------>
        // COLOR_BURN 亮化/暗化
        // BlendMode.COLOR_DODGE 白花
        // BlendMode.EXCLUSION 红
        // outlineCir透明
        // this.percentLabel.setBlendMode(BlendMode.COLOR_BURN);
        // ------------------------------------------------------>
        // CSS样式: ballindicator-border-circle
        // this.outlineCir.setStrokeWidth(2.00f);
        // this.outlineCir.setStroke(Color.BLUE); // 最终的边框?
        // this.outlineCir.setFill(Color.TRANSPARENT); // 空白的色
        // 堆叠Shape和outlineCir
        this.container.setPrefWidth(widthPrefSize);
        this.container.setPrefHeight(heightPrefSize);
        this.container.setMaxWidth(widthPrefSize);
        this.container.setMaxHeight(heightPrefSize);
        this.container.getChildren().addAll(outlineCir, paintPath, percentLabel);

    }
    // 使用样式文件更新组件
    private void initStyles(){
        // 填充
        this.progessCir.getStyleClass().add("ballindicator-filler-circle");
        this.paintPath.getStyleClass().add("ballindicator-filler-circle");
        // 边框
        this.outlineCir.getStyleClass().add("ballindicator-border-circle");
        // 进度值
        this.percentLabel.getStyleClass().add("ballindicator-label");
        // 颜色调和
        Blend blend = new Blend();
        // 方案2
        blend.setTopInput(new Shadow(0.5f,Core.toColor("#000000")));
        blend.setMode(BlendMode.ADD);
        this.percentLabel.setEffect(blend);
    }
    // 更新进度球水平线
    private void updateWaterline(double height){
        // 高度的合理区间
        // 增长
        // 防止变型(衰减)
        if(height > this.container.getMaxHeight()){
            return;
        }
        // 遮盖矩形的高度
        this.coverRec.setHeight(height);
        // 重新计算：遮盖遮盖与底部圆的区域
        Path temp = (Path)Shape.subtract(this.progessCir, this.coverRec);
        // 清空原来的
        this.paintPath.getElements().clear();
        // 将结果压入Path
        this.paintPath.getElements().addAll(temp.getElements());
    }
    // 更新进度值
    private void setProgressLabel(int value) {
        if (value >= 0) {
            percentLabel.setText(String.format("%d%%", value));
        }
    }
}
